package com.bosssoft.boss_exam_core.common.config.security;


import com.bosssoft.boss_exam_core.util.web.RequestContextUtil;
import com.bosssoft.boss_exam_db.entity.Admin;

import com.bosssoft.boss_exam_db.entity.Role;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * jwt token
 * @since 2017/6/28
 */
public class AdminJwtTokenHelper {

    /**
     * token过期时间
     */
    public static final long VALIDITY_TIME_MS = 24 * 60 * 60 * 1000; // 24 hours  validity
    //        设置过期时间为1天

    /**
     * header中标识
     */
    public static final String AUTH_HEADER_NAME = "x-authorization";

    /**
     * 签名密钥
     */
//  jwt token签名密钥
    private static final String SECRET = "bosssoft";


    /**
     * @param admin
     * @return
     */
    public String create(Admin admin) {

        return Jwts.builder()
                .setExpiration(new Date(System.currentTimeMillis() + VALIDITY_TIME_MS))
                .claim("id", admin.getId())
                .claim("username", admin.getUsername())
                .claim("avatar", admin.getAvatar())
                .claim("roles", admin.getRoles())
                .signWith(SignatureAlgorithm.HS256, SECRET)
                .compact();
    }

    /**
     * 获取token的过期时间
     * @return
     */
    public Date getExpiration(String token){
        Claims claims = Jwts.parser()
                .setSigningKey(SECRET)
                .parseClaimsJws(token)
                .getBody();
        Date expirationDate = claims.getExpiration();
        return expirationDate;
    }

    /**
     * 验签
     */
    public Optional<Admin> verifyToken(HttpServletRequest request) {
        final String token = request.getHeader(AUTH_HEADER_NAME);
        if (!StringUtils.isEmpty(token)) {
            final Admin admin = parse(token.trim());
            // 校验token时间是否过期
            Date expirationDate = getExpiration(token.trim());
            Date currentDate = new Date();
            //过期
            if (expirationDate.getTime()<currentDate.getTime()){
                return Optional.empty();
            }else {
                //判断该token是否有效
                if (admin != null) {
                    //返回身份验证（通过）
                    return Optional.of(admin);
                }
            }
        }
        return Optional.empty();
    }


    /**
     * 从token中取出管理员信息
     */
    public Admin parse(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(SECRET)
                .parseClaimsJws(token)
                .getBody();
        Admin admin = new Admin();
        admin.setId(claims.get("id", String.class));
        admin.setUsername(claims.get("username", String.class));
        admin.setAvatar(claims.get("avatar", String.class));
        admin.setRoles((List<Role>) claims.get("roles"));
        ArrayList<Role> roles = new ArrayList<>();
        ArrayList<HashMap<String, Object>> roleObjList = (ArrayList<HashMap<String, Object>>) claims.get("roles");
        for (HashMap<String, Object> map : roleObjList) {
            Role role = new Role();
            role.setId((String) map.get("id"));
            role.setName((String) map.get("name"));
            role.setNameZh((String) map.get("nameZh"));
            role.setDeleted((Boolean)map.get("deleted"));
            role.setVersion((Integer) map.get("version"));
            roles.add(role);
        }
        admin.setRoles(roles);
        return admin;
    }

    /**
     * 验签
     */
    public Optional<Admin> getCurrentLoginUser() {
        HttpServletRequest request = RequestContextUtil.getRequest();
        Optional<Admin> adminOptional = verifyToken(request);
        return adminOptional;
    }
}
